#include "type.h"
#include "const.h"
#include "protect.h"
#include "proto.h"
#include "string.h"
#include "proc.h"
#include "global.h"

public int kernel_main()
{
    // sub esp, 12
    // push  0x00032310
    // call disp_str
    // add esp, 16
    disp_str("----\"kernel_main\" begins-----\n");
    // mov [ebp - 12], 0x000354c0
    Process* p_proc = proc_table;

    // mov eax, [ebp - 12]
    // mov [eax + 72], 0x28
    p_proc->ldt_sel = SELECTOR_LDT_FIRST;

// 以下是真实的汇编代码
    // mov eax, dword [ebp - 12]
    // add eax, 74
    // sub esp, 4
    // push 8
    // push 0x00034828
    // push eax
    // call memcpy
    // add esp, 16

    // 以下是我写的汇编（没有想到编译器会自动计算）
    // mov ax, 0x8
    // shl ax, 3
    // movzx eax, ax
    // mov edx, 0x00034820(0, eax, 8)
    // mov eax, dword [ebp - 12]
    // add eax, 74
    // push 8
    // push eax
    // push edx
    // call memcpy
    memcpy(&p_proc->ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(Descriptor));
    // mov eax, dword [ebp - 12] ; p_proc
    // mov byte [eax + 79], 0xb8
    p_proc->ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5;

    memcpy(&p_proc->ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(Descriptor));
    p_proc->ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5;

    p_proc->regs.cs = (0 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
    p_proc->regs.ds = (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
    p_proc->regs.es = (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
    p_proc->regs.fs = (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
    p_proc->regs.ss = (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
    p_proc->regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_TASK;
    p_proc->regs.eip = (u32) testA;
    // 地址0x30fa4 这段稍微没看懂
    // mov eax, 0x00035540
    // lea edx, ds:[eax+32768]
    // mov eax, dword ptr ss:[ebp-12]
    //  mov dword ptr ds:[eax+64], edx
    p_proc->regs.esp = (u32) task_stack + STACK_SIZE_TOTAL;
    p_proc->regs.eflags = 0x1202;

    // mov [ds:0x000354a0], 0x000354c0
    p_proc_ready = proc_table;
    restart();

    while (1)
    {
        
    }
    
}

void testA()
{
    int i = 0;
    while(1)
    {
        disp_str("A");
        disp_int(i++);
        disp_str(".");
        delay(1);
    }
}